Skip to content

Fix wavelet tree get_segment crash for alphabet_size=1#60

Open
kilo-code-bot[bot] wants to merge 1 commit into
mainfrom
fix/wavelet-tree-get-segment-npos-crash
Open

Fix wavelet tree get_segment crash for alphabet_size=1#60
kilo-code-bot[bot] wants to merge 1 commit into
mainfrom
fix/wavelet-tree-get-segment-npos-crash

Conversation

@kilo-code-bot

@kilo-code-bot kilo-code-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a crash in WaveletTreeIndex::get_segment_impl when alphabet_size == 1 (or any case where root_ == npos with data_size_ > 0).

Related to #41 (Wavelet tree implementation with general rank/select).

Bug

When alphabet_size == 1, the wavelet tree has no internal nodes (root_ == npos). The get_segment_impl method unconditionally called copy_segment_content(root_, ...), which accessed nodes_[npos] — an out-of-bounds index since nodes_ is empty.

rank_impl and select_impl already handled root_ == npos correctly (the traversal loop simply does not execute), but get_segment_impl had no guard for this degenerate case.

Fix

Add an early return in get_segment_impl when root_ == npos. In this case all symbols are identical, so the result is inverse_permutation_.front() repeated (end - begin) times.

Test coverage additions

  • AlphabetSizeOne: rank, select, and get_segment for single-symbol alphabets (both Standard and Huffman builds). This test would have crashed before the fix.
  • AlphabetSizeZero: empty alphabet edge case
  • EmptyData: non-empty alphabet with no data
  • SymbolWithZeroOccurrences: symbols present in the alphabet but absent from the data
  • AllSameSymbolLargeAlphabet: one symbol repeated with a large alphabet where most symbols have zero occurrences

Files changed

  • include/pixie/wavelet_tree/index.h: 5-line fix in get_segment_impl
  • src/tests/wavelet_tree_tests.cpp: 4 new test cases covering edge cases

When alphabet_size == 1, the wavelet tree has no internal nodes
(root_ == npos). The get_segment_impl method unconditionally called
copy_segment_content(root_, ...) which accessed nodes_[npos], causing
an out-of-bounds access since nodes_ is empty.

rank_impl and select_impl already handled root_ == npos correctly
(the traversal loop simply does not execute), but get_segment_impl
had no guard for this degenerate case.

Fix: add an early return in get_segment_impl when root_ == npos.
In this case all symbols are identical, so the result is the single
symbol (inverse_permutation_.front()) repeated (end - begin) times.

Also add edge-case test coverage:
- AlphabetSizeOne: rank, select, and get_segment for single-symbol
  alphabets (both Standard and Huffman builds)
- AlphabetSizeZero: empty alphabet edge case
- EmptyData: non-empty alphabet with no data
- SymbolWithZeroOccurrences: symbols present in the alphabet but
  absent from the data
- AllSameSymbolLargeAlphabet: one symbol repeated with a large
  alphabet where most symbols have zero occurrences
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.21%. Comparing base (bf01091) to head (94f8ac6).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #60      +/-   ##
==========================================
+ Coverage   90.10%   90.21%   +0.11%     
==========================================
  Files          39       39              
  Lines        8735     8783      +48     
  Branches     1418     1433      +15     
==========================================
+ Hits         7871     7924      +53     
+ Misses        447      443       -4     
+ Partials      417      416       -1     
Flag Coverage Δ
gcov 90.21% <100.00%> (+0.11%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Malkovsky

Copy link
Copy Markdown
Owner

This kind of things should probably be handled in constructor, the case of alphabet size 1 is indeed of no use

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant